﻿using System;
using Assets.Scripts.GtsScripts;
using UnityEngine;

// Token: 0x02000155 RID: 341
[AddComponentMenu("RVP/C#/Damage/Vehicle Damage", 0)]
[DisallowMultipleComponent]
[RequireComponent(typeof(VehicleParent))]
public class VehicleDamage : MonoBehaviour
{
	// Token: 0x06000621 RID: 1569 RVA: 0x00032FE8 File Offset: 0x000311E8
	private void Start()
	{
		this.tr = base.transform;
		this.rb = base.GetComponent<Rigidbody>();
		this.vp = base.GetComponent<VehicleParent>();
		this.vp.playCrashSounds = false;
		this.vp.playCrashSparks = false;
		this.tempMeshes = new Mesh[this.deformMeshes.Length];
		this.damagedMeshes = new bool[this.deformMeshes.Length];
		this.meshVertices = new meshVerts[this.deformMeshes.Length];
		for (int i = 0; i < this.deformMeshes.Length; i++)
		{
			this.tempMeshes[i] = this.deformMeshes[i].mesh;
			this.meshVertices[i] = new meshVerts();
			this.meshVertices[i].verts = this.deformMeshes[i].mesh.vertices;
			this.meshVertices[i].initialVerts = this.deformMeshes[i].mesh.vertices;
			this.damagedMeshes[i] = false;
		}
		this.tempCols = new Mesh[this.deformColliders.Length];
		this.damagedCols = new bool[this.deformColliders.Length];
		this.colVertices = new meshVerts[this.deformColliders.Length];
		for (int j = 0; j < this.deformColliders.Length; j++)
		{
			this.tempCols[j] = UnityEngine.Object.Instantiate<Mesh>(this.deformColliders[j].sharedMesh);
			this.colVertices[j] = new meshVerts();
			this.colVertices[j].verts = this.deformColliders[j].sharedMesh.vertices;
			this.colVertices[j].initialVerts = this.deformColliders[j].sharedMesh.vertices;
			this.damagedCols[j] = false;
		}
		this.initialPartPositions = new Vector3[this.displaceParts.Length];
		for (int k = 0; k < this.displaceParts.Length; k++)
		{
			this.initialPartPositions[k] = this.displaceParts[k].localPosition;
		}
	}

	// Token: 0x06000622 RID: 1570 RVA: 0x000331F6 File Offset: 0x000313F6
	private void FixedUpdate()
	{
		this.hitTime = Mathf.Max(0f, this.hitTime - Time.fixedDeltaTime);
		this.damageFactor = Mathf.Max(0f, this.damageFactor);
	}

	// Token: 0x06000623 RID: 1571 RVA: 0x0003322C File Offset: 0x0003142C
	private void OnCollisionEnter(Collision col)
	{
		Debug.Log("collision!" + col.collider.gameObject.name);
		bool flag = this.IsGiantessDamage(col);
		if ((this.hitTime == 0f && col.relativeVelocity.sqrMagnitude * this.damageFactor > 1f && this.strength < 1f) || flag)
		{
			Vector3 normalized = col.relativeVelocity.normalized;
			int num = 0;
			bool flag2 = false;
			bool flag3 = false;
			this.hitTime = this.collisionTimeGap;
			foreach (ContactPoint colPoint in col.contacts)
			{
				if (this.tr.InverseTransformPoint(colPoint.point).y > this.collisionIgnoreHeight && GlobalControl.damageMaskStatic == (GlobalControl.damageMaskStatic | 1 << colPoint.otherCollider.gameObject.layer))
				{
					num++;
					if (this.vp.crashSnd && this.vp.crashClips.Length > 0 && !flag2)
					{
						this.vp.crashSnd.PlayOneShot(this.vp.crashClips[UnityEngine.Random.Range(0, this.vp.crashClips.Length)], Mathf.Clamp01(col.relativeVelocity.magnitude * 0.1f));
						flag2 = true;
					}
					if (this.vp.sparks && !flag3)
					{
						this.vp.sparks.transform.position = colPoint.point;
						this.vp.sparks.transform.rotation = Quaternion.LookRotation(normalized, colPoint.normal);
						this.vp.sparks.Play();
						flag3 = true;
					}
					this.DamageApplication(colPoint.point, col.relativeVelocity, this.maxCollisionMagnitude, colPoint.normal, colPoint, true, flag);
				}
				if (num >= this.maxCollisionPoints)
				{
					break;
				}
			}
			this.FinalizeDamage(flag);
		}
	}

	// Token: 0x06000624 RID: 1572 RVA: 0x0003347B File Offset: 0x0003167B
	private bool IsGiantessDamage(Collision col)
	{
		return col.collider.transform.root.GetComponent<Giantess>() != null;
	}

	// Token: 0x06000625 RID: 1573 RVA: 0x00033498 File Offset: 0x00031698
	public void ApplyDamage(ContactPoint colPoint, Vector3 colVel, bool isGiantess)
	{
		this.DamageApplication(colPoint.point, colVel, float.PositiveInfinity, colPoint.normal, colPoint, true, isGiantess);
		this.FinalizeDamage(isGiantess);
	}

	// Token: 0x06000626 RID: 1574 RVA: 0x000334BE File Offset: 0x000316BE
	public void ApplyDamage(ContactPoint colPoint, Vector3 colVel, float damageForceLimit, bool isGiantess)
	{
		this.DamageApplication(colPoint.point, colVel, damageForceLimit, colPoint.normal, colPoint, true, isGiantess);
		this.FinalizeDamage(isGiantess);
	}

	// Token: 0x06000627 RID: 1575 RVA: 0x000334E2 File Offset: 0x000316E2
	public void ApplyDamage(Vector3 damagePoint, Vector3 damageForce, bool isGiantess)
	{
		this.DamageApplication(damagePoint, damageForce, float.PositiveInfinity, damageForce.normalized, this.nullContact, false, isGiantess);
		this.FinalizeDamage(isGiantess);
	}

	// Token: 0x06000628 RID: 1576 RVA: 0x00033507 File Offset: 0x00031707
	public void ApplyDamage(Vector3 damagePoint, Vector3 damageForce, float damageForceLimit, bool isGiantess)
	{
		this.DamageApplication(damagePoint, damageForce, damageForceLimit, damageForce.normalized, this.nullContact, false, isGiantess);
		this.FinalizeDamage(isGiantess);
	}

	// Token: 0x06000629 RID: 1577 RVA: 0x0003352C File Offset: 0x0003172C
	public void ApplyDamage(Vector3[] damagePoints, Vector3 damageForce, bool isGiantess)
	{
		foreach (Vector3 damagePoint in damagePoints)
		{
			this.DamageApplication(damagePoint, damageForce, float.PositiveInfinity, damageForce.normalized, this.nullContact, false, isGiantess);
		}
		this.FinalizeDamage(isGiantess);
	}

	// Token: 0x0600062A RID: 1578 RVA: 0x00033580 File Offset: 0x00031780
	public void ApplyDamage(Vector3[] damagePoints, Vector3 damageForce, float damageForceLimit, bool isGiantess)
	{
		foreach (Vector3 damagePoint in damagePoints)
		{
			this.DamageApplication(damagePoint, damageForce, damageForceLimit, damageForce.normalized, this.nullContact, false, isGiantess);
		}
		this.FinalizeDamage(isGiantess);
	}

	// Token: 0x0600062B RID: 1579 RVA: 0x000335D4 File Offset: 0x000317D4
	private void DamageApplication(Vector3 damagePoint, Vector3 damageForce, float damageForceLimit, Vector3 surfaceNormal, ContactPoint colPoint, bool useContactPoint, bool isGiantess)
	{
		float num = Mathf.Min(damageForce.magnitude, this.maxCollisionMagnitude) * (1f - this.strength) * this.damageFactor;
		float num2 = Mathf.Pow(Mathf.Sqrt(num) * 0.5f, 1.5f);
		Vector3 vector = Vector3.ClampMagnitude(damageForce, damageForceLimit);
		Vector3 normalized = damageForce.normalized;
		float num3 = 1f;
		Transform transform = null;
		if (isGiantess)
		{
			if (this.IsCrushed)
			{
				return;
			}
			this.IsCrushed = true;
		}
		if (useContactPoint)
		{
			damagePoint = colPoint.point;
			surfaceNormal = colPoint.normal;
			if (colPoint.otherCollider.attachedRigidbody)
			{
				num3 = Mathf.Clamp01(colPoint.otherCollider.attachedRigidbody.mass / this.rb.mass);
			}
		}
		float num4 = Mathf.Clamp01(Vector3.Dot(surfaceNormal, normalized)) * (Vector3.Dot((this.tr.position - damagePoint).normalized, normalized) + 1f) * 0.5f;
		for (int i = 0; i < this.damageParts.Length; i++)
		{
			Transform transform2 = this.damageParts[i];
			float num5 = num * num4 * num3 * Mathf.Min(num2 * 0.01f, num2 * 0.001f / Mathf.Pow(Vector3.Distance(transform2.position, damagePoint), num2));
			Motor component = transform2.GetComponent<Motor>();
			if (component)
			{
				if (isGiantess)
				{
					component.health -= 90f;
				}
				else
				{
					component.health -= num5 * (1f - component.strength);
				}
			}
			Transmission component2 = transform2.GetComponent<Transmission>();
			if (component2)
			{
				component2.health -= num5 * (1f - component2.strength);
			}
		}
		for (int j = 0; j < this.deformMeshes.Length; j++)
		{
			MeshFilter meshFilter = this.deformMeshes[j];
			Vector3 b = meshFilter.transform.InverseTransformPoint(damagePoint);
			Vector3 vector2 = meshFilter.transform.InverseTransformDirection(vector);
			Vector3 a = Vector3.ClampMagnitude(vector2, num2);
			ShatterPart component3 = meshFilter.GetComponent<ShatterPart>();
			if (component3)
			{
				transform = component3.seamKeeper;
				if ((Vector3.Distance(meshFilter.transform.position, damagePoint) < num * num4 * 0.1f * num3 && num * num4 * num3 > component3.breakForce) || isGiantess)
				{
					component3.Shatter();
				}
			}
			if ((vector2.sqrMagnitude > 0f && this.strength < 1f) || isGiantess)
			{
				for (int k = 0; k < this.meshVertices[j].verts.Length; k++)
				{
					float f = Vector3.Distance(this.meshVertices[j].verts[k], b);
					float num6 = num2 * 0.001f / Mathf.Pow(f, num2);
					if (num6 > 0.001f || isGiantess)
					{
						this.damagedMeshes[j] = true;
						if (transform == null || this.seamlessDeform)
						{
							Vector3 a2 = (!this.seamlessDeform) ? Vector3.Project(normalized, this.meshVertices[j].verts[k]) : Vector3.zero;
							this.meshVertices[j].verts[k] += (a - a2 * ((!this.usePerlinNoise) ? 1f : (1f + Mathf.PerlinNoise(this.meshVertices[j].verts[k].x * 100f, this.meshVertices[j].verts[k].y * 100f)))) * num4 * Mathf.Min(num2 * 0.01f, num6) * num3;
						}
						else
						{
							Vector3 onNormal = transform.InverseTransformPoint(meshFilter.transform.TransformPoint(this.meshVertices[j].verts[k]));
							this.meshVertices[j].verts[k] += (a - Vector3.Project(normalized, onNormal) * ((!this.usePerlinNoise) ? 1f : (1f + Mathf.PerlinNoise(onNormal.x * 100f, onNormal.y * 100f)))) * num4 * Mathf.Min(num2 * 0.01f, num6) * num3;
						}
					}
				}
			}
		}
		for (int l = 0; l < this.deformColliders.Length; l++)
		{
			Vector3 b = this.deformColliders[l].transform.InverseTransformPoint(damagePoint);
			Vector3 vector2 = this.deformColliders[l].transform.InverseTransformDirection(vector);
			Vector3 a = Vector3.ClampMagnitude(vector2, num2);
			if (vector2.sqrMagnitude > 0f && this.strength < 1f)
			{
				for (int m = 0; m < this.colVertices[l].verts.Length; m++)
				{
					float f = Vector3.Distance(this.colVertices[l].verts[m], b);
					float num6 = num2 * 0.001f / Mathf.Pow(f, num2);
					if (num6 > 0.001f || isGiantess)
					{
						this.damagedCols[l] = true;
						this.colVertices[l].verts[m] += a * num4 * Mathf.Min(num2 * 0.01f, num6) * num3;
					}
				}
			}
		}
		for (int n = 0; n < this.displaceParts.Length; n++)
		{
			Transform transform3 = this.displaceParts[n];
			Vector3 vector2 = vector;
			Vector3 a = Vector3.ClampMagnitude(vector2, num2);
			if ((vector2.sqrMagnitude > 0f && this.strength < 1f) || isGiantess)
			{
				float f = Vector3.Distance(transform3.position, damagePoint);
				float num6 = num2 * 0.001f / Mathf.Pow(f, num2);
				if (isGiantess)
				{
					num6 = 0.3f;
					num3 = 100f;
				}
				if (num6 > 0.001f)
				{
					transform3.position += a * num4 * Mathf.Min(num2 * 0.01f, num6) * num3;
					if (transform3.GetComponent<DetachablePart>())
					{
						DetachablePart component4 = transform3.GetComponent<DetachablePart>();
						if ((num * num4 * num3 > component4.looseForce && component4.looseForce >= 0f) || isGiantess)
						{
							component4.initialPos = transform3.localPosition;
							component4.Detach(true);
						}
						else if (num * num4 * num3 > component4.breakForce)
						{
							component4.Detach(false);
						}
					}
					else if (transform3.parent.GetComponent<DetachablePart>())
					{
						DetachablePart component4 = transform3.parent.GetComponent<DetachablePart>();
						if (!component4.detached)
						{
							if ((num * num4 * num3 > component4.looseForce && component4.looseForce >= 0f) || isGiantess)
							{
								component4.initialPos = transform3.parent.localPosition;
								component4.Detach(true);
							}
							else if (num * num4 * num3 > component4.breakForce)
							{
								component4.Detach(false);
							}
						}
						else if (component4.hinge)
						{
							component4.displacedAnchor += transform3.parent.InverseTransformDirection(a * num4 * Mathf.Min(num2 * 0.01f, num6) * num3);
						}
					}
					Suspension component5 = transform3.GetComponent<Suspension>();
					if (component5 && ((!component5.wheel.grounded && this.ignoreGroundedWheels) || !this.ignoreGroundedWheels || isGiantess))
					{
						transform3.RotateAround(component5.tr.TransformPoint(component5.damagePivot), Vector3.ProjectOnPlane(damagePoint - transform3.position, -vector2.normalized), num2 * num4 * num6 * 20f * num3);
						component5.wheel.damage += num2 * num4 * num6 * 10f * num3;
						if (num2 * num4 * num6 * 10f * num3 > component5.jamForce)
						{
							component5.jammed = true;
						}
						if (num2 * num4 * num6 * 10f * num3 > component5.wheel.detachForce)
						{
							component5.wheel.Detach();
						}
						foreach (SuspensionPart suspensionPart in component5.movingParts)
						{
							if (suspensionPart.connectObj && !suspensionPart.isHub && !suspensionPart.solidAxle && !suspensionPart.connectObj.GetComponent<SuspensionPart>())
							{
								suspensionPart.connectPoint += suspensionPart.connectObj.InverseTransformDirection(a * num4 * Mathf.Min(num2 * 0.01f, num6) * num3);
							}
						}
					}
					HoverWheel component6 = transform3.GetComponent<HoverWheel>();
					if (component6 && ((!component6.grounded && this.ignoreGroundedWheels) || !this.ignoreGroundedWheels || isGiantess) && num2 * num4 * num6 * 10f * num3 > component6.detachForce)
					{
						component6.Detach();
					}
				}
			}
		}
	}

	// Token: 0x0600062C RID: 1580 RVA: 0x00034080 File Offset: 0x00032280
	private void FinalizeDamage(bool isGiantess)
	{
		for (int i = 0; i < this.deformMeshes.Length; i++)
		{
			if (this.damagedMeshes[i] || isGiantess)
			{
				this.tempMeshes[i].vertices = this.meshVertices[i].verts;
				if (this.calculateNormals)
				{
					this.tempMeshes[i].RecalculateNormals();
				}
				this.tempMeshes[i].RecalculateBounds();
			}
			this.damagedMeshes[i] = false;
		}
		for (int j = 0; j < this.deformColliders.Length; j++)
		{
			if (this.damagedCols[j] || isGiantess)
			{
				this.tempCols[j].vertices = this.colVertices[j].verts;
				this.deformColliders[j].sharedMesh = null;
				this.deformColliders[j].sharedMesh = this.tempCols[j];
			}
			this.damagedCols[j] = false;
		}
	}

	// Token: 0x0600062D RID: 1581 RVA: 0x00034174 File Offset: 0x00032374
	public void Repair()
	{
		this.IsCrushed = false;
		for (int i = 0; i < this.damageParts.Length; i++)
		{
			if (this.damageParts[i].GetComponent<Motor>())
			{
				this.damageParts[i].GetComponent<Motor>().health = 1f;
			}
			if (this.damageParts[i].GetComponent<Transmission>())
			{
				this.damageParts[i].GetComponent<Transmission>().health = 1f;
			}
		}
		for (int j = 0; j < this.deformMeshes.Length; j++)
		{
			for (int k = 0; k < this.meshVertices[j].verts.Length; k++)
			{
				this.meshVertices[j].verts[k] = this.meshVertices[j].initialVerts[k];
			}
			this.tempMeshes[j].vertices = this.meshVertices[j].verts;
			this.tempMeshes[j].RecalculateNormals();
			this.tempMeshes[j].RecalculateBounds();
			ShatterPart component = this.deformMeshes[j].GetComponent<ShatterPart>();
			if (component)
			{
				component.shattered = false;
				if (component.brokenMaterial)
				{
					component.rend.sharedMaterial = component.initialMat;
				}
				else
				{
					component.rend.enabled = true;
				}
			}
		}
		for (int l = 0; l < this.deformColliders.Length; l++)
		{
			for (int m = 0; m < this.colVertices[l].verts.Length; m++)
			{
				this.colVertices[l].verts[m] = this.colVertices[l].initialVerts[m];
			}
			this.tempCols[l].vertices = this.colVertices[l].verts;
			this.deformColliders[l].sharedMesh = null;
			this.deformColliders[l].sharedMesh = this.tempCols[l];
		}
		for (int n = 0; n < this.displaceParts.Length; n++)
		{
			Transform transform = this.displaceParts[n];
			transform.localPosition = this.initialPartPositions[n];
			if (transform.GetComponent<DetachablePart>())
			{
				transform.GetComponent<DetachablePart>().Reattach();
			}
			else if (transform.parent.GetComponent<DetachablePart>())
			{
				transform.parent.GetComponent<DetachablePart>().Reattach();
			}
			Suspension component2 = transform.GetComponent<Suspension>();
			if (component2)
			{
				transform.localRotation = component2.initialRotation;
				component2.jammed = false;
				foreach (SuspensionPart suspensionPart in component2.movingParts)
				{
					if (suspensionPart.connectObj && !suspensionPart.isHub && !suspensionPart.solidAxle && !suspensionPart.connectObj.GetComponent<SuspensionPart>())
					{
						suspensionPart.connectPoint = suspensionPart.initialConnectPoint;
					}
				}
			}
		}
		foreach (Wheel wheel in this.vp.wheels)
		{
			wheel.Reattach();
			wheel.FixTire();
			wheel.damage = 0f;
		}
		foreach (HoverWheel hoverWheel in this.vp.hoverWheels)
		{
			hoverWheel.Reattach();
		}
	}

	// Token: 0x0600062E RID: 1582 RVA: 0x0003456C File Offset: 0x0003276C
	private void OnDrawGizmosSelected()
	{
		Vector3 from = base.transform.TransformPoint(Vector3.up * this.collisionIgnoreHeight);
		Gizmos.color = Color.red;
		Gizmos.DrawRay(from, base.transform.forward);
		Gizmos.DrawRay(from, -base.transform.forward);
		Gizmos.DrawRay(from, base.transform.right);
		Gizmos.DrawRay(from, -base.transform.right);
	}

	// Token: 0x0600062F RID: 1583 RVA: 0x000345F0 File Offset: 0x000327F0
	private void OnDestroy()
	{
		foreach (Transform transform in this.displaceParts)
		{
			if (transform)
			{
				if (transform.GetComponent<DetachablePart>() && transform.parent == null)
				{
					UnityEngine.Object.Destroy(transform.gameObject);
				}
				else if (transform.parent.GetComponent<DetachablePart>() && transform.parent.parent == null)
				{
					UnityEngine.Object.Destroy(transform.parent.gameObject);
				}
			}
		}
	}

	// Token: 0x0400099C RID: 2460
	private Transform tr;

	// Token: 0x0400099D RID: 2461
	private Rigidbody rb;

	// Token: 0x0400099E RID: 2462
	private VehicleParent vp;

	// Token: 0x0400099F RID: 2463
	[Range(0f, 1f)]
	public float strength;

	// Token: 0x040009A0 RID: 2464
	public float damageFactor = 1f;

	// Token: 0x040009A1 RID: 2465
	public float maxCollisionMagnitude = 100f;

	// Token: 0x040009A2 RID: 2466
	[Tooltip("Maximum collision points to use when deforming, has large effect on performance")]
	public int maxCollisionPoints = 2;

	// Token: 0x040009A3 RID: 2467
	[Tooltip("Collisions underneath this local y-position will be ignored")]
	public float collisionIgnoreHeight;

	// Token: 0x040009A4 RID: 2468
	[Tooltip("If true, grounded wheels will not be damaged, but can still be displaced")]
	public bool ignoreGroundedWheels;

	// Token: 0x040009A5 RID: 2469
	[Tooltip("Minimum time in seconds between collisions")]
	public float collisionTimeGap = 0.1f;

	// Token: 0x040009A6 RID: 2470
	private float hitTime;

	// Token: 0x040009A7 RID: 2471
	[Tooltip("Whether the edges of adjacent deforming parts should match")]
	public bool seamlessDeform;

	// Token: 0x040009A8 RID: 2472
	[Tooltip("Add some perlin noise to deformation")]
	public bool usePerlinNoise = true;

	// Token: 0x040009A9 RID: 2473
	[Tooltip("Recalculate normals of deformed meshes")]
	public bool calculateNormals = true;

	// Token: 0x040009AA RID: 2474
	[Tooltip("Parts that are damaged")]
	public Transform[] damageParts;

	// Token: 0x040009AB RID: 2475
	[Tooltip("Meshes that are deformed")]
	public MeshFilter[] deformMeshes;

	// Token: 0x040009AC RID: 2476
	private bool[] damagedMeshes;

	// Token: 0x040009AD RID: 2477
	private Mesh[] tempMeshes;

	// Token: 0x040009AE RID: 2478
	private meshVerts[] meshVertices;

	// Token: 0x040009AF RID: 2479
	[Tooltip("Mesh colliders that are deformed (Poor performance, must be convex)")]
	public MeshCollider[] deformColliders;

	// Token: 0x040009B0 RID: 2480
	private bool[] damagedCols;

	// Token: 0x040009B1 RID: 2481
	private Mesh[] tempCols;

	// Token: 0x040009B2 RID: 2482
	private meshVerts[] colVertices;

	// Token: 0x040009B3 RID: 2483
	[Tooltip("Parts that are displaced")]
	public Transform[] displaceParts;

	// Token: 0x040009B4 RID: 2484
	private Vector3[] initialPartPositions;

	// Token: 0x040009B5 RID: 2485
	private ContactPoint nullContact = default(ContactPoint);

	// Token: 0x040009B6 RID: 2486
	private bool IsCrushed;
}
